home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / dev / lang / FPL_v147.lha / fpl / src / debugmem.c < prev    next >
C/C++ Source or Header  |  1996-08-02  |  11KB  |  428 lines

  1. #ifdef RCS
  2. static char rcsid[] = "$Id: debugmem.c,v 1.2 1996/02/29 14:10:50 dast Exp $";
  3. #endif
  4. /******************************************************************************
  5.  *                        FRONTEC RAILWAY SYSTEMS AB
  6.  * ----------------------------------------------------------------------------
  7.  *
  8.  * Project: FR-3000 CS
  9.  * $Source: /home/pop/proj/rail/usr/dast/dancer/dancer/RCS/debugmem.c,v $
  10.  * $Revision: 1.2 $
  11.  * $Date: 1996/02/29 14:10:50 $
  12.  * $Author: dast $
  13.  * $State: Exp $
  14.  * $Locker:  $
  15.  *
  16.  * ----------------------------------------------------------------------------
  17.  * $Log: debugmem.c,v $
  18.  * Revision 1.2  1996/02/29 14:10:50  dast
  19.  * small change
  20.  *
  21.  * Revision 1.1  1996/01/18 12:32:11  dast
  22.  * Initial revision
  23.  *
  24.  * Revision 3.7  1994/11/30  08:58:22  dast
  25.  * Fixed a bug in the header
  26.  *
  27.  *****************************************************************************/
  28.  
  29.  
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include <stdlib.h>
  33.  
  34. #ifdef AMIGA
  35. #include <exec/types.h>
  36. #include <exec/memory.h>
  37. #include <proto/exec.h>
  38. #endif
  39.  
  40. #include "debugmem.h"
  41.  
  42. /*
  43. #undef malloc
  44. #undef free
  45. */
  46.  
  47. static int bytes_alloc_I=0;
  48. static struct DebugMem *MallocKey =NULL;
  49. static char Verbose=0;
  50.  
  51. struct DebugMem {
  52.     struct DebugMem *prev;
  53.     struct DebugMem *next;
  54.     int size_I;
  55. #ifdef SOURCE_INFO
  56.     char *source_PC;
  57.     int line_I;
  58. #endif
  59. };
  60.  
  61. void UnLinkMemory( struct DebugMem * );
  62. void LinkMemory ( struct DebugMem * );
  63.  
  64. /*************************************************************************
  65. *
  66. * Function   : DBG_realloc
  67. * Purpose    : Debug version of the system function realloc()
  68. * Parameters : memory pointer, new size, source file, line number
  69. * Returns    : new allocation or NULL if failed
  70. *
  71. ****************************************************************************/
  72.  
  73. void * DBG_realloc( OldBuf_P, size_I, source_PC, line_I )
  74.      void *        OldBuf_P;
  75.      int         size_I;    
  76.      char *        source_PC;
  77.      int        line_I;
  78. {
  79.     struct DebugMem *debug_PS;
  80.     void    *NewBuf_P;
  81.  
  82.     if ( OldBuf_P == NULL )
  83.         /* *NOT* ANSI return!!! */
  84.         return DBG_malloc( size_I, source_PC, line_I );
  85.  
  86.     debug_PS = (struct DebugMem *)
  87.         ((char *) OldBuf_P - sizeof( struct DebugMem ) - PRE_COOKIE_SIZE);
  88.  
  89. #if 0
  90.     /* this code prevents reallocing to less size */
  91.     if ( size_I <= debug_PS->size_I )
  92.         return OldBuf_P;
  93. #endif
  94.  
  95.     if ( (NewBuf_P = DBG_malloc( size_I, source_PC, line_I )) == NULL )
  96.         return NULL;
  97.  
  98.     memcpy( NewBuf_P, OldBuf_P, debug_PS->size_I );
  99.     DBG_free( OldBuf_P, source_PC, line_I );
  100.     return NewBuf_P;
  101. }
  102.  
  103. /***************************************************************************
  104. *
  105. * Function   : DBG_Verbose
  106. * Purpose    : Switch on verbose mode for debugging
  107. * Parameters : TRUE/FALSE
  108. * Returns    : none
  109. *
  110. *****************************************************************************/
  111.  
  112. void DBG_Verbose (char verbose_C)
  113. {
  114.     Verbose = verbose_C;
  115. }
  116.  
  117. /*************************************************************************
  118. *
  119. * Function   : DBG_calloc
  120. * Purpose    : Add debug level to the system function calloc()
  121. * Parameters : number of itmes, itemsize, source file, line
  122. * Returns    : allocated [cleared] memory or NULL if failed
  123. *
  124. **********************************************************************/
  125.  
  126. void * DBG_calloc ( items_I, itemsize_I, source_PC, line_I )
  127.      int         items_I;
  128.      int         itemsize_I;
  129.      char *        source_PC;
  130.      int        line_I;
  131. {
  132.   int size_I = items_I * itemsize_I;
  133.   void *mem = DBG_malloc(size_I, source_PC, line_I);
  134.   if(mem)
  135.     memset(mem, 0, size_I); /* clear it */
  136.   return mem;
  137. }
  138.  
  139. /*************************************************************************
  140. *
  141. * Function   : DBG_malloc
  142. * Purpose    : Add debug level to the system function malloc()
  143. * Parameters : size, source file, line
  144. * Returns    : allocated memory or NULL if failed
  145. *
  146. **********************************************************************/
  147.  
  148. void * DBG_malloc ( size_I, source_PC, line_I )
  149.      int         size_I;    
  150.      char *        source_PC;
  151.      int        line_I;
  152. {
  153.     struct DebugMem *debug_PS;
  154.     void *p;
  155.  
  156.     /* Get some extra memory to make room for an extra
  157.        integer storage to store the malloc()'ed size! */
  158.  
  159.     debug_PS = (struct DebugMem *) _MALLOC( size_I +
  160.                           sizeof( struct DebugMem ) +
  161.                           PRE_COOKIE_SIZE +
  162.                           POST_COOKIE_SIZE, MEMF_ANY );
  163.  
  164.     if ( !debug_PS )
  165.         return NULL;
  166.     
  167.     if(Verbose) {
  168.         MALLOCED(size_I, source_PC, line_I);
  169.     }
  170.     /* The malloc() did succeed */
  171.     debug_PS->size_I = size_I ; /* remember size of malloc() */
  172.     bytes_alloc_I += size_I ; /* count the malloc()s */
  173.  
  174.     LinkMemory( debug_PS );
  175.     
  176. #ifdef SOURCE_INFO
  177.     debug_PS->source_PC = source_PC;
  178.     debug_PS->line_I    = line_I;
  179. #endif
  180.     
  181. #if PRE_COOKIE_SIZE > 0
  182.     memset((char*)debug_PS + sizeof( struct DebugMem ), PRE_COOKIE_FILL_BYTE,
  183.            PRE_COOKIE_SIZE);
  184. #endif
  185.     
  186. #if POST_COOKIE_SIZE > 0
  187.     memset((char*)debug_PS + sizeof( struct DebugMem ) + size_I + PRE_COOKIE_SIZE,
  188.            POST_COOKIE_FILL_BYTE, POST_COOKIE_SIZE);
  189. #endif
  190.     
  191.  
  192.     p = (char*)debug_PS + sizeof( struct DebugMem ) + PRE_COOKIE_SIZE;
  193.     
  194.     return p;
  195. }
  196.  
  197. /********************************************************************
  198.  *
  199.  * Function   : DBG_free
  200.  * Purpose    : Add debug level to the system function free()
  201.  * Parameters : memory pointer, source file, source line
  202.  * Returns    : none
  203.  *
  204.  ***********************************************************************/
  205.  
  206. void DBG_free ( mem_P,
  207. #ifdef FREE_WITH_SIZE
  208.                 size_I,
  209. #endif
  210.                 source_PC, line_I )
  211.      void *        mem_P;
  212. #ifdef FREE_WITH_SIZE
  213.          int        size_I;
  214. #endif
  215.      char *        source_PC;
  216.      int        line_I;
  217. {
  218.     struct DebugMem *debug_PS;
  219.  
  220.     if( !mem_P) {
  221. #ifdef LOG
  222.         Logf("DEBUG", "Freeing NULL pointer at %s line %d\n",
  223.              source_PC, line_I);
  224. #endif
  225.         return;
  226.     }
  227.     debug_PS = (struct DebugMem *)
  228.         ((char *) mem_P - sizeof( struct DebugMem ) - PRE_COOKIE_SIZE);
  229.  
  230.     DBG__CheckMem(mem_P, source_PC, line_I);
  231.  
  232.     bytes_alloc_I -= debug_PS->size_I;
  233.  
  234.     if(Verbose) {
  235.         FREED(debug_PS->size_I, source_PC, line_I);
  236.     }
  237.     UnLinkMemory( debug_PS );
  238. #ifdef FREE_WITH_SIZE
  239.     FREE_WITH_SIZE( debug_PS, size_I );
  240. #else
  241.     _FREE( debug_PS );
  242. #endif
  243.  
  244. }
  245.  
  246.  
  247. /***************************************************************************
  248.  *
  249.  * Function   : DBG_UsedMem
  250.  * Purpose    : Return number of allocated bytes.
  251.  * Parameters : none
  252.  * Returns    : Number of bytes
  253.  *
  254.  ***************************************************************************/
  255.  
  256. int DBG_UsedMem( )
  257. {
  258.     return bytes_alloc_I;
  259. }
  260.  
  261. /*************************************************************************
  262.  *
  263.  * Function   : DBG__CheckMem
  264.  * Purpose    : Check the cookies around the memory allocation for overwritten
  265.  *              memory areas!
  266.  * Parameters : memory pointer, source file, source line
  267.  *
  268.  ***************************************************************************/
  269.  
  270. long DBG__CheckMem ( mem_P, source_PC, line_I )
  271.      void *        mem_P;
  272.      char *        source_PC;
  273.      int        line_I;
  274. {
  275.     struct DebugMem *debug_PS;
  276.     int        a, b, c;
  277.  
  278.     debug_PS = (struct DebugMem *)
  279.         ((char *) mem_P - sizeof( struct DebugMem ) - PRE_COOKIE_SIZE);
  280.  
  281. #if PRE_COOKIE_SIZE > 0
  282.     for(a=b=0; a<PRE_COOKIE_SIZE; a++)
  283.         if( *((unsigned char *)mem_P - PRE_COOKIE_SIZE + a ) != PRE_COOKIE_FILL_BYTE )
  284.             b++;
  285.     if ( b ) {
  286.         PRE_COOKIE_ACTION(b, source_PC, line_I
  287.                           , debug_PS->source_PC, debug_PS->line_I
  288.                           );
  289.     }
  290. #endif
  291.  
  292. #if POST_COOKIE_SIZE > 0
  293.     for(a=c=0; a<POST_COOKIE_SIZE; a++)
  294.         if(*((unsigned char *)mem_P + debug_PS->size_I + a) != POST_COOKIE_FILL_BYTE)
  295.             c++;
  296.     if ( c ) {
  297.         POST_COOKIE_ACTION(c, source_PC, line_I, debug_PS->source_PC, debug_PS->line_I );
  298.     }
  299. #endif
  300.  
  301.     if(Verbose) {
  302.         CHECKMEMED(debug_PS->size_I, source_PC, line_I);
  303.     }
  304.  
  305.     return b + c;
  306. }
  307.  
  308. /***************************************************************************
  309.  *
  310.  * Function   : DBG_Strdup
  311.  * Purpose    : Replaces the system strdup() function for debugging.
  312.  * Parameters : string, source file, source line
  313.  * Returns    : Allocated string or NULL if failed
  314.  *
  315.  **************************************************************************/
  316.  
  317. char *DBG_Strdup(char *string_PC, char *source_PC, int line_I)
  318. {
  319.     int len   = strlen( string_PC );
  320.     char *ptr = DBG_malloc( len+1, source_PC, line_I );
  321.     if(ptr)
  322.         strcpy(ptr, string_PC);
  323.     return ptr;
  324. }
  325.  
  326. /*************************************************************************
  327.  *
  328.  * Function   : DBG_MemList
  329.  * Purpose    : Display all allocations on stdout!
  330.  * Parameters : none
  331.  * Returns    : none
  332.  *
  333.  *************************************************************************/
  334.  
  335. void DBG_MemList()
  336. {
  337.     struct     DebugMem *point = MallocKey;
  338.     
  339.     printf("------> Total %d bytes <------\n",
  340.            DBG_UsedMem());
  341.     
  342.     while(point) {
  343.         printf("source: %s line: %d size: %d\n",
  344.                point->source_PC,
  345.                point->line_I,
  346.                point->size_I);
  347.         point = point->prev;
  348.     } 
  349.  
  350.     printf("------> End of table <------\n");
  351. }
  352.  
  353. /**********************************************************************
  354.  *
  355.  * Function   : LinkMemory
  356.  * Purpose    : Link a memory pointer to the linked list of memory.
  357.  * Parameters : (struct DebugMem *) to the memory to add
  358.  * Returns    : none
  359.  *
  360.  ************************************************************************/
  361.  
  362. void LinkMemory(point)
  363.      struct DebugMem *point;
  364. {
  365.     point->prev=MallocKey;     /* previous */
  366.     point->next=NULL;         /* next */
  367.     if(MallocKey)
  368.         point->prev->next=point;
  369.     MallocKey = (void *)point;
  370. }
  371.  
  372. /**********************************************************************
  373.  *
  374.  * Function   : UnLinkMemory
  375.  * Purpose    : Remove a memory area from the linked list.
  376.  * Parameters : (struct DebugMem *) to the area to remove
  377.  * Returns    : none
  378.  *
  379.  ************************************************************************/
  380.  
  381. void UnLinkMemory(point)
  382.      struct DebugMem *point;
  383. {
  384.     if(MallocKey==point) {
  385.         /* if this is the last Malloc, set `last' to `prev' */
  386.         MallocKey=point->prev;
  387.         if(MallocKey)
  388.             MallocKey->next=NULL;
  389.     } else {
  390.         /* point the previous' `next' to our `next', and our next `previous'
  391.            to our `previous'. Unlink us from the chain */
  392.         if(point->prev)
  393.             /* only if we aren't the _first_ Malloc() ! */
  394.             point->prev->next=point->next;
  395.         if(point->next)
  396.             /* only if there is a next! */
  397.             point->next->prev=point->prev;
  398.     }
  399. }
  400.  
  401. /***********************************************************************
  402.  *
  403.  * Function   : FreeAll
  404.  * Purpose    : Free all memory areas in the list
  405.  * Parameters : none
  406.  * Returns    : none
  407.  *
  408.  *************************************************************************/
  409.  
  410. void FreeAll()
  411. {
  412.     struct DebugMem *point;
  413.     struct DebugMem *prev;
  414.  
  415.     if(!MallocKey)
  416.         return;
  417.         
  418.     do {
  419.         point = MallocKey;
  420.         
  421.         prev = point->prev;
  422.         
  423.         free(point);
  424.     } while(MallocKey = prev);
  425.  
  426. }
  427.  
  428.